package com.cysyz.mylib.dao.impl;

import com.cysyz.mylib.dao.PagingResult;
import com.cysyz.mylib.dao.SqlBaseDao;
import com.cysyz.mylib.dao.engine.PersistenceEngine;
import com.cysyz.mylib.dao.engine.SQLQuery;

import java.util.List;

/**
 * DAO实现类
 * @ClassName: BaseDaoImpl
 * @author 崔勇	cysyz1229@gmail.com
 * @Date 2014-4-24 下午3:15:43
 */
class SqlDaoImpl implements SqlBaseDao {

    private static int MAX_RESULT_PER_PAGE = 100;

    private PersistenceEngine persistenceEngine;

    public SqlDaoImpl(PersistenceEngine persistenceEngine) {
        this.persistenceEngine = persistenceEngine;
    }


    @Override
    public <T> long getCount(String ql, List<Object> params) {
        StringBuilder sqlBuilder = new StringBuilder("select count(*) as c from (");
        sqlBuilder.append(ql);
        sqlBuilder.append(") tmp_count_t");
        SQLQuery sqlQuery = configSQLQuery(sqlBuilder.toString(), params);
        return ((Long) sqlQuery.getSingleResult()).longValue();
    }

    private SQLQuery configSQLQuery(String sql, List<Object> params) {
        SQLQuery sqlQuery = persistenceEngine.createSQLQuery(sql);
        setParams(params, sqlQuery);
        return sqlQuery;
    }

    private void setParams(List<Object> params, SQLQuery sqlQuery) {
        int i = 1;
        for (Object param : params) {
            sqlQuery.setParameter(i ++, param);
        }
    }

    @Override
    public void execute(String ql, List<Object> params) {
        SQLQuery sqlQuery = configSQLQuery(ql, params);
        sqlQuery.execute();
    }

    @Override
    public List<Object[]> list(String ql, List<Object> params) {
        SQLQuery sqlQuery = configSQLQuery(ql, params);
        return sqlQuery.getResultList();
    }

    public Object get(String ql, List<Object> params) {
        SQLQuery sqlQuery = configSQLQuery(ql, params);
        return sqlQuery.getResultList();
    }

    private SQLQuery configSQLQuery(String sql, List<Object> params, String mappingInfo) {
        SQLQuery sqlQuery = persistenceEngine.createSQLQuery(sql, mappingInfo);
        setParams(params, sqlQuery);
        return sqlQuery;
    }

    @Override
    public <T> PagingResult<T> listPaging(String ql, List<Object> params, Class<T> resultClazz, String mappingInfo, int page, int maxResult) {

        maxResult = checkResultPerPage(maxResult);

        if (page <= 0) {
            page = 1;
        }

        SQLQuery sqlQuery = configSQLQuery(ql, params, mappingInfo);

        if (page>=0 && maxResult>=0) sqlQuery.setFirstResult((page - 1) * maxResult).setMaxResults(maxResult);

        List<T> resultList = sqlQuery.getResultList();

        long totalRecords = getCount(ql, params);

        PagingResult<T> pagingResult = new PagingResult<T>(resultList, totalRecords, page, maxResult);

        return pagingResult;
    }

    private int checkResultPerPage(int maxResult) {
        if (maxResult > MAX_RESULT_PER_PAGE) {
            maxResult = MAX_RESULT_PER_PAGE;
        }
        return maxResult;
    }

}
